JavaScript—Map vs. ForEach

原文链接 有删节
javascript中的 mapforEach 方法有什么共同点和区别呢?

也许你在工作中已经接触到了 Array.prototype.map()Array.prototype.forEach() 那么他们有什么不同呢?

Map & ForEach 的定义

首先,我们开一下 MDN上的定义

  • forEach()) 方法对数组的每个元素执行一次提供的函数。
  • map()方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
    具体是什么意思呢?
    forEach() 方法不会返回任何有用的值,他的返回值是 undefined。forEach 方法按升序为数组中含有效值的每一项执行一次callback 函数,在这个回调函数中允许你去改变原来的数组。
    map() 方法会给原数组中的每个元素都按顺序调用一次 callback 函数。不同点是callback 每次执行后的返回值(包括 undefined)组合起来形成一个新数组。

    示例

    考虑下面的一个数组,如果我们想让数组的每一项的值变成原来的两倍,我们可以用 mapforEach
    1
    let arr = [1, 2, 3, 4, 5];

forEach
注意:你不能从 forEach 通过 return 返回你想要的值,return 的值会被自动忽略。
code

1
2
3
arr.forEach((num, index) => {
return arr[index] = num * 2;
});

result

1
// arr = [2, 4, 6, 8, 10]

map
code

1
2
3
let doubled = arr.map(num => {
return num * 2;
});

result

1
// doubled = [2, 4, 6, 8, 10]

性能

下面的图片展示了测试性能


真如你所看到的,在我的电脑上 forEach()map() 慢了70%,根据电脑配置和浏览器不同,这个测试结果会有差异,你可以在jsPerf上运行这个测试用例。

函数式编程的考虑

函数式编程是一件非常有意思的事情。
如果你喜欢函数式编程,那么理解 map() 方法是很重要的。因为 forEach() 方法很可能会改变原来的数组,map() 则会返回一个新的数组 ,保证原数组不会被修改。

谁才是更好的选择呢?

这就要看你的需求了。

对于 ForEach(),如果你不想更改数组中的数据,而是想用它做一些事情,比如将其保存到数据库或在控制台输出,那么他是一个不错的选择。

1
2
3
4
5
6
7
8
let arr = ['a', 'b', 'c', 'd'];
arr.forEach((letter) => {
console.log(letter);
});
// a
// b
// c
// d

在需要更改数据时,map() 可能更可取。 它不仅速度更快,而且返回一个新的数组。 这意味着我们可以和其他方法(map(),filter(),reduce()等)一起实现链式调用。

1
2
3
let arr = [1, 2, 3, 4, 5];
let arr2 = arr.map(num => num * 2).filter(num => num > 5);
// arr2 = [6, 8, 10]

上面的方法,我们先 把 arr 的每一项变成原来的两倍,然后再过滤出 大于5的元素,最后得到一个新的数组 arr2

总结

  • map() 会分配内存并存储返回的值, forEach()返回的值永远是 undefined
  • forEach()允许你再回调函数中改变原来的数组, map() 则会返回一个新的数组。

参考链接

JavaScript — Map vs. ForEach – codeburst